package l1j.server.server.model.damage.hit;

import static l1j.server.server.model.skill.L1SkillId.COUNTER_BARRIER;
import l1j.server.server.model.L1Magic;
import l1j.server.server.model.Instance.L1NpcInstance;
import l1j.server.server.model.Instance.L1PcInstance;
import l1j.server.server.model.Instance.L1PetInstance;
import l1j.server.server.model.Instance.L1SummonInstance;
import l1j.server.server.model.damage.L1Dmg;
import l1j.server.server.types.Point;
import l1j.server.server.utils.Random;

public class L1Hit_Npc_Pc extends L1Hit{
	private L1NpcInstance _attacker;

	private L1PcInstance _target;
	
	private L1NpcHit _npcHit;
	public L1Hit_Npc_Pc(L1NpcInstance attacker, L1PcInstance target) {
		_attacker = attacker;
		_target = target;
		_npcHit = new L1NpcHit(attacker,target);
	}

	public boolean calcHit(){
		_npcHit.doAttackAction();
		if (_target.isInvincible())
			return false;
		clacNpcPcHit();
		return _isHit;
	}
	
	private void clacNpcPcHit(){
		_hitRate = _npcHit.calcNpcHitRate(_hitRate);
		
		L1OnPcHit oph = new L1OnPcHit(_target);
		_hitRate = oph.hitRateOnPc(_hitRate);

		_isHit = Random.chance100(_hitRate);
		
		if ((_attacker instanceof L1PetInstance)
				|| (_attacker instanceof L1SummonInstance)) {
			// 目標在安區、攻擊者在安區、NOPVP
			if ((_target.getZoneType() == 1) || (_attacker.getZoneType() == 1)
					|| (_target.checkNonPvP(_target, _attacker))) {
				_hitRate = 0;
			}
		}
		
		if ((_attacker.getAtkRanged() >= 10)
				&& _isHit
				&& (_attacker.getLocation().getTileLineDistance(
						_target.getLocation()) >= 2)) {
			_isHit = calcErEvasion();
		}
		
		if(_isHit && _target.hasSkillEffect(COUNTER_BARRIER)){
			L1Magic magic = new L1Magic(_target, _attacker);
			if(magic.calcProbabilityMagic(COUNTER_BARRIER)){
				boolean isCounter = true;
				boolean isLongRange = (_attacker.getLocation().getTileLineDistance(
						new Point(_target.getX(), _target.getY())) > 1);
				int bowActId = _attacker.getPolyArrowGfx();
				if (bowActId == 0) {
					bowActId = _attacker.getNpcTemplate().getBowActId();
				}
				// 距離が2以上、攻撃者の弓のアクションIDがある場合は遠攻撃
				if (isLongRange && (bowActId > 0)) {
					isCounter = false;
				}
				if(isCounter){
					L1Dmg counterDmg = L1Dmg.get(true, 0, _target, _attacker);
					oph.actionCounterBarrier(counterDmg);
					_isHit = false;
				}
			}
		}
	}
	
	// ●●●● ＥＲによる回避判定 ●●●●
		private boolean calcErEvasion() {
			int er = _target.getEr();
			int rnd = Random.nextInt(100) + 1;
			return er < rnd;
		}
}
